cmake_minimum_required(VERSION 3.2...3.5 FATAL_ERROR)

PROJECT(units LANGUAGES CXX)
set(units_VERSION 2.3.1)

# check if this is the main project
set(MAIN_PROJECT OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
  	set(MAIN_PROJECT ON)
endif()

# cmake options
OPTION(BUILD_TESTS "Build unit tests" ${MAIN_PROJECT})
OPTION(BUILD_DOCS "Build the documentation" OFF)
OPTION(DISABLE_IOSTREAM "Disables <iostream> (cout) support for embedded applications" OFF)

# options to disable unit definitions. Turn these on for unused namespaces to improve compile speed
OPTION(DISABLE_PREDEFINED_UNITS "Disables all library-defined units" OFF)

# options to re-enable specific unit types. Only use these if DISABLE_PREDEFINED_UNITS is set to ON
OPTION(ENABLE_PREDEFINED_LENGTH_UNITS "Enables library-defined units of LENGTH." OFF)
OPTION(ENABLE_PREDEFINED_MASS_UNITS "Enables library-defined units of MASS." OFF)
OPTION(ENABLE_PREDEFINED_TIME_UNITS "Enables library-defined units of TIME." OFF)
OPTION(ENABLE_PREDEFINED_ANGLE_UNITS "Enables library-defined units of ANGLE." OFF)
OPTION(ENABLE_PREDEFINED_CURRENT_UNITS "Enables library-defined units of CURRENT." OFF)
OPTION(ENABLE_PREDEFINED_TEMPERATURE_UNITS "Enables library-defined units of TEMPERATURE." OFF)
OPTION(ENABLE_PREDEFINED_SUBSTANCE_UNITS "Enables library-defined units of SUBSTANCE." OFF)
OPTION(ENABLE_PREDEFINED_LUMINOUS_INTENSITY_UNITS "Enables library-defined units of LUMINOUS INTENSITY." OFF)
OPTION(ENABLE_PREDEFINED_SOLID_ANGLE_UNITS "Enables library-defined units of SOLID ANGLE." OFF)
OPTION(ENABLE_PREDEFINED_FREQUENCY_UNITS "Enables library-defined units of FREQUENCY." OFF)
OPTION(ENABLE_PREDEFINED_VELOCITY_UNITS "Enables library-defined units of VELOCITY." OFF)
OPTION(ENABLE_PREDEFINED_ANGULAR_VELOCITY_UNITS "Enables library-defined units of ANGULAR VELOCITY." OFF)
OPTION(ENABLE_PREDEFINED_ACCELERATION_UNITS "Enables library-defined units of ACCELERATION." OFF)
OPTION(ENABLE_PREDEFINED_FORCE_UNITS "Enables library-defined units of FORCE." OFF)
OPTION(ENABLE_PREDEFINED_PRESSURE_UNITS "Enables library-defined units of PRESSURE." OFF)
OPTION(ENABLE_PREDEFINED_CHARGE_UNITS "Enables library-defined units of CHARGE." OFF)
OPTION(ENABLE_PREDEFINED_ENERGY_UNITS "Enables library-defined units of ENERGY." OFF)
OPTION(ENABLE_PREDEFINED_POWER_UNITS "Enables library-defined units of POWER." OFF)
OPTION(ENABLE_PREDEFINED_VOLTAGE_UNITS "Enables library-defined units of VOLTAGE." OFF)
OPTION(ENABLE_PREDEFINED_CAPACITANCE_UNITS "Enables library-defined units of CAPACITANCE." OFF)
OPTION(ENABLE_PREDEFINED_IMPEDANCE_UNITS "Enables library-defined units of IMPEDANCE." OFF)
OPTION(ENABLE_PREDEFINED_MAGNETIC_FLUX_UNITS "Enables library-defined units of MAGNETIC FLUX." OFF)
OPTION(ENABLE_PREDEFINED_MAGNETIC_FIELD_STRENGTH_UNITS "Enables library-defined units of MAGNETIC FIELD STRENGTH." OFF)
OPTION(ENABLE_PREDEFINED_INDUCTANCE_UNITS "Enables library-defined units of INDUCTANCE." OFF)
OPTION(ENABLE_PREDEFINED_LUMINOUS_FLUX_UNITS "Enables library-defined units of LUMINOUS FLUX." OFF)
OPTION(ENABLE_PREDEFINED_ILLUMINANCE_UNITS "Enables library-defined units of ILLUMINANCE." OFF)
OPTION(ENABLE_PREDEFINED_RADIATION_UNITS "Enables library-defined units of RADIATION." OFF)
OPTION(ENABLE_PREDEFINED_TORQUE_UNITS "Enables library-defined units of TORQUE." OFF)
OPTION(ENABLE_PREDEFINED_AREA_UNITS "Enables library-defined units of AREA." OFF)
OPTION(ENABLE_PREDEFINED_VOLUME_UNITS "Enables library-defined units of VOLUME." OFF)
OPTION(ENABLE_PREDEFINED_DENSITY_UNITS "Enables library-defined units of DENSITY." OFF)
OPTION(ENABLE_PREDEFINED_CONCENTRATION_UNITS "Enables library-defined units of CONCENTRATION." OFF)
OPTION(ENABLE_PREDEFINED_DATA_UNITS "Enables library-defined units of DATA." OFF)
OPTION(ENABLE_PREDEFINED_DATA_TRANSFER_RATE_UNITS "Enables library-defined units of DATA TRANSFER RATE." OFF)
OPTION(ENABLE_PREDEFINED_CONSTANTS_UNITS "Enables library-defined units of CONSTANTS." OFF)

SET(CMAKE_CXX_STANDARD 14)
SET(CMAKE_CXX_STANDARD_REQUIRED TRUE)

# header-only library target. To use this project as a subdirectory,
# add the following to your code:
#
# add_subdirectory(units) # or whatever you named the directory
# target_link_libraries(${PROJECT_NAME} units)
add_library(${PROJECT_NAME} INTERFACE)
add_library(units::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

target_include_directories(${PROJECT_NAME} 
	INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> 
	$<INSTALL_INTERFACE:include> 
)

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
	# enable parallel build
	set( ENV{CL} /MP )
	target_compile_options(${PROJECT_NAME} INTERFACE /permissive-)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
	# Increase warning levels
	add_compile_options(-Wall -Wextra -pedantic)
endif()

# Remove IOStream from the library (useful for embdedded development)
if(DISABLE_IOSTREAM)
	target_compile_definitions(${PROJECT_NAME} INTERFACE -DUNIT_LIB_DISABLE_IOSTREAM)
endif(DISABLE_IOSTREAM)

# unit tests
if(BUILD_TESTS)
	set(VERSION_GTEST "1.8.0" CACHE STRING "Google Test framework version")
	enable_testing()
	add_subdirectory(3rdParty/gtest)
	add_subdirectory(unitTests)
endif(BUILD_TESTS)

#enable specific unit definitions
if(DISABLE_PREDEFINED_UNITS)
	target_compile_definitions(${PROJECT_NAME} INTERFACE -DDISABLE_PREDEFINED_UNITS)
endif(DISABLE_PREDEFINED_UNITS)

if(ENABLE_PREDEFINED_LENGTH_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_LENGTH_UNITS)
endif(ENABLE_PREDEFINED_LENGTH_UNITS)
if(ENABLE_PREDEFINED_MASS_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_MASS_UNITS)
endif(ENABLE_PREDEFINED_MASS_UNITS)
if(ENABLE_PREDEFINED_TIME_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_TIME_UNITS)
endif(ENABLE_PREDEFINED_TIME_UNITS)
if(ENABLE_PREDEFINED_ANGLE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_ANGLE_UNITS)
endif(ENABLE_PREDEFINED_ANGLE_UNITS)
if(ENABLE_PREDEFINED_CURRENT_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_CURRENT_UNITS)
endif(ENABLE_PREDEFINED_CURRENT_UNITS)
if(ENABLE_PREDEFINED_TEMPERATURE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_TEMPERATURE_UNITS)
endif(ENABLE_PREDEFINED_TEMPERATURE_UNITS)
if(ENABLE_PREDEFINED_SUBSTANCE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_SUBSTANCE_UNITS)
endif(ENABLE_PREDEFINED_SUBSTANCE_UNITS)
if(ENABLE_PREDEFINED_LUMINOUS_INTENSITY_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_LUMINOUS_INTENSITY_UNITS)
endif(ENABLE_PREDEFINED_LUMINOUS_INTENSITY_UNITS)
if(ENABLE_PREDEFINED_SOLID_ANGLE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_SOLID_ANGLE_UNITS)
endif(ENABLE_PREDEFINED_SOLID_ANGLE_UNITS)
if(ENABLE_PREDEFINED_FREQUENCY_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_FREQUENCY_UNITS)
endif(ENABLE_PREDEFINED_FREQUENCY_UNITS)
if(ENABLE_PREDEFINED_VELOCITY_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_VELOCITY_UNITS)
endif(ENABLE_PREDEFINED_VELOCITY_UNITS)
if(ENABLE_PREDEFINED_ANGULAR_VELOCITY_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_ANGULAR_VELOCITY_UNITS)
endif(ENABLE_PREDEFINED_ANGULAR_VELOCITY_UNITS)
if(ENABLE_PREDEFINED_ACCELERATION_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_ACCELERATION_UNITS)
endif(ENABLE_PREDEFINED_ACCELERATION_UNITS)
if(ENABLE_PREDEFINED_FORCE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_FORCE_UNITS)
endif(ENABLE_PREDEFINED_FORCE_UNITS)
if(ENABLE_PREDEFINED_PRESSURE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_PRESSURE_UNITS)
endif(ENABLE_PREDEFINED_PRESSURE_UNITS)
if(ENABLE_PREDEFINED_CHARGE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_CHARGE_UNITS)
endif(ENABLE_PREDEFINED_CHARGE_UNITS)
if(ENABLE_PREDEFINED_ENERGY_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_ENERGY_UNITS)
endif(ENABLE_PREDEFINED_ENERGY_UNITS)
if(ENABLE_PREDEFINED_POWER_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_POWER_UNITS)
endif(ENABLE_PREDEFINED_POWER_UNITS)
if(ENABLE_PREDEFINED_VOLTAGE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_VOLTAGE_UNITS)
endif(ENABLE_PREDEFINED_VOLTAGE_UNITS)
if(ENABLE_PREDEFINED_CAPACITANCE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_CAPACITANCE_UNITS)
endif(ENABLE_PREDEFINED_CAPACITANCE_UNITS)
if(ENABLE_PREDEFINED_IMPEDANCE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_IMPEDANCE_UNITS)
endif(ENABLE_PREDEFINED_IMPEDANCE_UNITS)
if(ENABLE_PREDEFINED_MAGNETIC_FLUX_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_MAGNETIC_FLUX_UNITS)
endif(ENABLE_PREDEFINED_MAGNETIC_FLUX_UNITS)
if(ENABLE_PREDEFINED_MAGNETIC_FIELD_STRENGTH_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_MAGNETIC_FIELD_STRENGTH_UNITS)
endif(ENABLE_PREDEFINED_MAGNETIC_FIELD_STRENGTH_UNITS)
if(ENABLE_PREDEFINED_INDUCTANCE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_INDUCTANCE_UNITS)
endif(ENABLE_PREDEFINED_INDUCTANCE_UNITS)
if(ENABLE_PREDEFINED_LUMINOUS_FLUX_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_LUMINOUS_FLUX_UNITS)
endif(ENABLE_PREDEFINED_LUMINOUS_FLUX_UNITS)
if(ENABLE_PREDEFINED_ILLUMINANCE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_ILLUMINANCE_UNITS)
endif(ENABLE_PREDEFINED_ILLUMINANCE_UNITS)
if(ENABLE_PREDEFINED_RADIATION_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_RADIATION_UNITS)
endif(ENABLE_PREDEFINED_RADIATION_UNITS)
if(ENABLE_PREDEFINED_TORQUE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_TORQUE_UNITS)
endif(ENABLE_PREDEFINED_TORQUE_UNITS)
if(ENABLE_PREDEFINED_AREA_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_AREA_UNITS)
endif(ENABLE_PREDEFINED_AREA_UNITS)
if(ENABLE_PREDEFINED_VOLUME_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_VOLUME_UNITS)
endif(ENABLE_PREDEFINED_VOLUME_UNITS)
if(ENABLE_PREDEFINED_DENSITY_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_DENSITY_UNITS)
endif(ENABLE_PREDEFINED_DENSITY_UNITS)
if(ENABLE_PREDEFINED_CONCENTRATION_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_CONCENTRATION_UNITS)
endif(ENABLE_PREDEFINED_CONCENTRATION_UNITS)
if(ENABLE_PREDEFINED_DATA_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_DATA_UNITS)
endif(ENABLE_PREDEFINED_DATA_UNITS)
if(ENABLE_PREDEFINED_DATA_TRANSFER_RATE_UNITS)
	 target_compile_definitions(${PROJECT_NAME} INTERFACE -DENABLE_PREDEFINED_DATA_TRANSFER_RATE_UNITS)
endif(ENABLE_PREDEFINED_DATA_TRANSFER_RATE_UNITS)

# add a target to generate API documentation with Doxygen
if(BUILD_DOCS)
	find_package(Doxygen)
	if(DOXYGEN_FOUND)
		configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
		add_custom_target(doc ALL
			${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
			WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs
			COMMENT "Generating API documentation with Doxygen" VERBATIM
		)
	endif(DOXYGEN_FOUND)
endif(BUILD_DOCS)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/unitsConfigVersion.cmake"
  VERSION ${units_VERSION}
  COMPATIBILITY SameMajorVersion
)

install(TARGETS units
    EXPORT unitsConfig
)

install(EXPORT unitsConfig
    NAMESPACE units::
    DESTINATION share/units/cmake
)

install(
    FILES "${CMAKE_CURRENT_BINARY_DIR}/unitsConfigVersion.cmake"
    DESTINATION share/units/cmake
)

install(DIRECTORY include/
    DESTINATION include
)
